----------------------------------------------------------------------------------------------------------------------------------------------------
--[[

    幽幽大行军：
    只能通过素鲍鱼附带或厨房的奇思妙想随机生成。
    效果：+7饱度，+77血，+49san，保质期777天，堆叠7，放在地上7秒后会像灰烬一样消失，可以装备在武器栏
    额外收获幽幽大行军时有台词：
    *点出【边界神游】后，食用后77秒内进入【通窍】状态，若生命值降到0，则立刻回复生命上限7%的生命并结束此状态.（希望有个屏幕边缘变高亮的特效）
    重复食用刷新时间至77秒。

    放在地上7秒后会自动转化为耐久为1次使用的【幽幽太行君】。

]]--
----------------------------------------------------------------------------------------------------------------------------------------------------
--- 素材
    local assets = {
        Asset("ANIM", "anim/hutao_cooked_food_ghostly_march.zip"), 
        Asset( "IMAGE", "images/inventoryimages/hutao_cooked_food_ghostly_march.tex" ),
        Asset( "ATLAS", "images/inventoryimages/hutao_cooked_food_ghostly_march.xml" ),

        Asset( "IMAGE", "images/widgets/hutao_debuff_ghostly_march_hud.tex" ),
        Asset( "ATLAS", "images/widgets/hutao_debuff_ghostly_march_hud.xml" ),
    }
----------------------------------------------------------------------------------------------------------------------------------------------------
--- PARAM
    local ON_GROUND_TRANS_TIME = 7  --- 放在地上 7 秒后转换
----------------------------------------------------------------------------------------------------------------------------------------------------
--- 
    local function IsTalentUnlocked(player)
        if TUNING.HUTAO_DEBUGGING_MODE then
            return true
        end
        if player.replica.hutao_com_talent_tree and player.replica.hutao_com_talent_tree:IsUnlocked("beyond_the_world") then
            return true
        end
        return false
    end
----------------------------------------------------------------------------------------------------------------------------------------------------
--- 丢地上转换
    local function GetTalkerOffset(inst)
        return Vector3(0,-200,0)
    end
    local function on_ground_task(inst)
        if inst.components.hutao_data:Get("trans_time") == nil then
            inst.components.hutao_data:Set("trans_time",ON_GROUND_TRANS_TIME + 1)
        end
        if inst.components.inventoryitem.owner ~= nil then
            inst.components.hutao_data:Set("trans_time",ON_GROUND_TRANS_TIME + 1)
        else
            local time = inst.components.hutao_data:Add("trans_time",-1)
            inst.components.talker:Say(tostring(time))
            if time <= 0 then
                if inst.components.lootdropper == nil then
                    inst:AddComponent("lootdropper")
                end
                local stack_num = inst.components.stackable:StackSize()
                local x,y,z = inst.Transform:GetWorldPosition()
                for i = 1, stack_num, 1 do
                    -- local item = SpawnPrefab("hutao_equipment_ghostly_march")
                    -- item.Transform:SetPosition(x,y,z)
                    local item = inst.components.lootdropper:SpawnLootPrefab("hutao_equipment_ghostly_march")
                    if item then
                        item:PushEvent("on_ground_transform")
                    end
                end
                SpawnPrefab("slurper_respawn").Transform:SetPosition(x,y,z)
                inst:Remove()
            end
        end
    end
    local function clear_talker(inst)
        inst.components.talker:Say(" ")
    end
----------------------------------------------------------------------------------------------------------------------------------------------------
--- 食物本体

    local function food_fn()

        local inst = CreateEntity() -- 创建实体
        inst.entity:AddTransform() -- 添加xyz形变对象
        inst.entity:AddAnimState() -- 添加动画状态
        inst.entity:AddNetwork() -- 添加这一行才能让所有客户端都能看到这个实体

        MakeInventoryPhysics(inst)

        inst.AnimState:SetBank("hutao_cooked_food_ghostly_march") -- 地上动画
        inst.AnimState:SetBuild("hutao_cooked_food_ghostly_march") -- 材质包，就是anim里的zip包
        inst.AnimState:PlayAnimation("idle") -- 默认播放哪个动画

        MakeInventoryFloatable(inst)
        inst:AddTag("preparedfood")

        inst.entity:SetPristine()
        --------------------------------------------------------------------------
        -- talker
            inst:AddComponent("talker")
            inst.components.talker:SetOffsetFn(GetTalkerOffset)
        --------------------------------------------------------------------------
        if not TheWorld.ismastersim then
            return inst
        end
        --------------------------------------------------------------------------
        --- 任务
            inst:DoPeriodicTask(1,on_ground_task)
            inst:ListenForEvent("onpickup",clear_talker)
        --------------------------------------------------------------------------
        --- 物品名 和检查文本
            inst:AddComponent("inspectable")

            inst:AddComponent("inventoryitem")
            -- inst.components.inventoryitem:ChangeImageName("leafymeatburger")
            inst.components.inventoryitem.imagename = "hutao_cooked_food_ghostly_march"
            inst.components.inventoryitem.atlasname = "images/inventoryimages/hutao_cooked_food_ghostly_march.xml"

        --------------------------------------------------------------------------
        --- 数据
            inst:AddComponent("hutao_data")
        --------------------------------------------------------------------------
        --- 食物组件

            inst:AddComponent("edible") -- 可食物组件
            inst.components.edible.foodtype = FOODTYPE.GOODIES
            inst.components.edible:SetOnEatenFn(function(inst,eater)
                if eater and eater:HasTag("hutao") and IsTalentUnlocked(eater) then
                    --------------------------------------------------------------------------------------------
                    --- 添加debuff
                        local debuff_prefab = "hutao_debuff_ghostly_march"
                        local debuff_inst = nil
                        local test_num = 100
                        while test_num > 0 do
                            debuff_inst = eater:GetDebuff(debuff_prefab)
                            if debuff_inst and debuff_inst:IsValid() then
                                break
                            end
                            eater:AddDebuff(debuff_prefab,debuff_prefab)
                            test_num = test_num - 1
                        end
                    --------------------------------------------------------------------------------------------
                    --- 台词控制器
                        if math.random() < 0.3 then
                            eater.components.hutao_com_dialogue:Say("eaten.ghostly_march")
                        end
                    --------------------------------------------------------------------------------------------
                end
            end)
            inst.components.edible.hungervalue = 7
            inst.components.edible.sanityvalue = 49
            inst.components.edible.healthvalue = 77
        --------------------------------------------------------------------------
        --- 可腐烂的组件
            inst:AddComponent("perishable")
            inst.components.perishable:SetPerishTime(77*TUNING.PERISH_ONE_DAY)
            inst.components.perishable:StartPerishing()
            inst.components.perishable.onperishreplacement = "spoiled_food" -- 腐烂后变成腐烂食物
        --------------------------------------------------------------------------
        -- 可堆叠
            inst:AddComponent("stackable")
            inst.components.stackable.maxsize = TUNING.STACK_SIZE_LARGEITEM
        --------------------------------------------------------------------------
        --- 可交易、作祟
            inst:AddComponent("tradable")
            MakeHauntableLaunch(inst)
        --------------------------------------------------------------------------
        --- 落水影子
            local function shadow_init(inst)
                if inst:IsOnOcean(false) then       --- 如果在海里（不包括船）
                    inst.AnimState:Hide("SHADOW")
                else                                
                    inst.AnimState:Show("SHADOW")
                end
            end
            inst:ListenForEvent("on_landed",shadow_init)
            shadow_init(inst)
        --------------------------------------------------------------------------
        
        return inst
    end
----------------------------------------------------------------------------------------------------------------------------------------------------
--- debuff
    local DEBUFF_TIMER_DELTA = 0.1              -- debuff 刷新检查时间
    local DEBUFF_REFRESH_TIME = TUNING.HUTAO_DEBUGGING_MODE and 20 or 77               -- debuff 时间

    local function OnAttached(inst,target) -- 玩家得到 debuff 的瞬间。 穿越洞穴、重新进存档 也会执行。
        inst.entity:SetParent(target.entity)
        -- inst.Network:SetClassifiedTarget(target)
        inst.Transform:SetPosition(0,0,0)
        inst.player = target
        -----------------------------------------------------
        --- 前置检查
            if target.components.health == nil then
                inst:Remove()
                return
            end
        -----------------------------------------------------
        --- 计时器初始化
            if inst.components.hutao_data:Add("time",0) == 0 then
                inst.components.hutao_data:Set("time",DEBUFF_REFRESH_TIME)
                inst.__net_time:set(DEBUFF_REFRESH_TIME)
                target.components.hutao_com_inspect_data:Set("hutao_debuff_ghostly_march",DEBUFF_REFRESH_TIME)
            end
            inst:DoPeriodicTask(DEBUFF_TIMER_DELTA,function()
                local ret_time = inst.components.hutao_data:Add("time",-DEBUFF_TIMER_DELTA)
                target.components.hutao_com_inspect_data:Set("hutao_debuff_ghostly_march",ret_time)
                inst.__net_time:set(ret_time)
                if ret_time <= 0 then
                    inst:Remove()
                    if target.components.hutao_com_dialogue then
                        target.components.hutao_com_dialogue:Say("eaten.debuff_remove.ghostly_march")
                    end
                end
            end)
            inst:ListenForEvent("onremove",function()
                target.components.hutao_com_inspect_data:Set("hutao_debuff_ghostly_march",0)                
            end)
        -----------------------------------------------------
        --- 配置net 目标
            inst.__net_target:set(target)
        -----------------------------------------------------
        --- 临死的瞬间
            inst:ListenForEvent("minhealth",function()
                local max_health = target.components.health.maxhealth
                local value = max_health*7/100
                target.components.health:DoDelta(value)
                inst:Remove()
            end,target)
        -----------------------------------------------------
    end

    local function ExtendDebuff(inst)
        inst.components.hutao_data:Set("time",DEBUFF_REFRESH_TIME)
    end

    local function create_buff_hud(inst)
        -----------------------------------------------------
        --- 预检查 和 模块引入
            local target = inst.__net_target:value()
            if not (target and target == ThePlayer and target.HUD) then
                return
            end
            local Widget = require "widgets/widget"
            local Image = require "widgets/image"
            local Text = require "widgets/text"
        -----------------------------------------------------
        --- 根节点
            local front_root = ThePlayer.HUD
            local root = front_root:AddChild(Widget())
            root:SetHAnchor(0) -- 设置原点x坐标位置，0、1、2分别对应屏幕中、左、右
            root:SetVAnchor(0) -- 设置原点y坐标位置，0、1、2分别对应屏幕中、上、下
            root:SetPosition(0,0)
            root:MoveToFront()
            root:SetScaleMode(SCALEMODE_FIXEDSCREEN_NONDYNAMIC)   --- 缩放模式
            root:SetClickable(false)
        -----------------------------------------------------
        ---
        -----------------------------------------------------
        --- 图层
            local img = root:AddChild(Image())
            img:SetTexture("images/widgets/hutao_debuff_ghostly_march_hud.xml","hutao_debuff_ghostly_march_hud.tex")
            local scale = 2.2
            img:SetScale(scale,scale,scale)
            img:SetFadeAlpha(0.4)
        -----------------------------------------------------
        --- 文本
            local time_str = root:AddChild(Text(CODEFONT,40,"",{ 255/255 , 255/255 ,255/255 , 1}))
            local time_pt = Vector3(-400,320,0)
            time_str:SetPosition(time_pt.x,time_pt.y)
        -----------------------------------------------------
        --- 晃动
            local function GetRandomOffset()
                local offset = math.random(8)
                if math.random() < 0.5 then
                    offset = -offset
                end
                return offset
            end
            root.inst:DoPeriodicTask(FRAMES*5,function()
                local offset_x,offset_y = GetRandomOffset(),GetRandomOffset()
                img:SetPosition(offset_x,offset_y)
                -- time_str:SetPosition(time_pt.x+offset_x,time_pt.y+offset_y)

                --- 保留小数点后一位。即便为0，也要显示 【12.0】
                local time = inst.__net_time:value()
                local str = string.format("%.1f",time)
                time_str:SetString(str)                
            end)
        -----------------------------------------------------
        --- 移除
            inst:ListenForEvent("onremove",function()
                root:Kill()
            end)
        -----------------------------------------------------
    end

    local function debuff_fn()
        local inst = CreateEntity()

        inst.entity:AddTransform()
        inst.entity:AddNetwork()
        inst.entity:AddTransform()

        inst:AddTag("CLASSIFIED")

        inst.entity:SetPristine()

        inst.__net_target = net_entity(inst.GUID,"ghostly_march_target","ghostly_march_target")
        inst.__net_time = net_float(inst.GUID,"ghostly_march_time")
        inst:ListenForEvent("ghostly_march_target",create_buff_hud)
        if not TheWorld.ismastersim then
            return inst
        end
        inst:AddComponent("hutao_data")
        inst:AddComponent("debuff")
        inst.components.debuff:SetAttachedFn(OnAttached)
        inst.components.debuff.keepondespawn = true -- 是否保持debuff 到下次登陆
        inst.components.debuff:SetExtendedFn(ExtendDebuff)

        return inst
    end
----------------------------------------------------------------------------------------------------------------------------------------------------

return Prefab("hutao_cooked_food_ghostly_march", food_fn, assets),
    Prefab("hutao_debuff_ghostly_march", debuff_fn, assets)